#include "softiic.h"
static void delay_us(int nus)
{
    volatile uint8_t i = 20;
    for(int j=0;j<i;j++)
        for(int k=0;k<nus;k++);
}
void IIC_Init(void)
{					     
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
//??IIC????
static void IIC_Start(void)
{
	SDA_H;	  	  
	SCL_H;
	delay_us(4);
 	SDA_L;//START:when CLK is high,DATA change form high to low 
	delay_us(4);
	SCL_L;//??I2C??,????????? 
}	  
//??IIC????
static void IIC_Stop(void)
{
	SCL_L;
	SDA_L;//STOP:when CLK is high DATA change form low to high
 	delay_us(4);
	SCL_H; 
	SDA_H;//??I2C??????
	delay_us(4);							   	
}
//????????
//???:1,??????
//        0,??????
static uint8_t IIC_Wait_Ack(void)
{
	uint8_t ucErrTime=0;
	SDA_H;delay_us(1);	   
	SCL_H;delay_us(1);	 
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	SCL_L;//????0 	   
	return 0;  
} 
//??ACK??
static void IIC_Ack(void)
{
	SCL_L;
	SDA_L;
	delay_us(2);
	SCL_H;
	delay_us(2);
	SCL_L;
}
//???ACK??		    
static void IIC_NAck(void)
{
	SCL_L;
	SDA_H;
	delay_us(2);
	SCL_H;
	delay_us(2);
	SCL_L;
}					 				     
//IIC??????
//????????
//1,???
//0,???			  
static void IIC_Send_Byte(uint8_t txd)
{                        
    uint8_t t;   
    SCL_L;//??????????
    for(t=0;t<8;t++)
    {              
		if((txd&0x80)>>7)
			SDA_H;
		else
			SDA_L;
		txd<<=1; 	  
		delay_us(4);   //?TEA5767??????????
		SCL_H;
		delay_us(4); 
		SCL_L;	
		delay_us(4);
    }	 
} 	    
//?1???,ack=1?,??ACK,ack=0,??nACK   
static uint8_t IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
    for(i=0;i<8;i++ )
	{
        SCL_L; 
        delay_us(7);
		SCL_H;
        receive<<=1;
        if(READ_SDA)receive++;   
		delay_us(5); 
    }					 
    if (!ack)
        IIC_NAck();//??nACK
    else
        IIC_Ack(); //??ACK   
    SDA_H;
    return receive;
}
void  SoftIIC_Write_Data(uint8_t daddr,uint8_t addr,uint8_t* data,uint16_t len)
{
    IIC_Start();
    IIC_Send_Byte(daddr<<1);
    IIC_Wait_Ack();
    IIC_Send_Byte(addr);
    IIC_Wait_Ack();
    for(int i=0;i<len;i++)
    {
        IIC_Send_Byte(data[i]);
        IIC_Wait_Ack();
    }
    IIC_Stop();
}
uint8_t SoftIIC_Read_Data (uint8_t daddr,uint8_t addr,uint8_t* data,uint16_t len)
{
    IIC_Start();
    IIC_Send_Byte(daddr<<1);
    IIC_Wait_Ack();
    IIC_Send_Byte(addr);
    IIC_Wait_Ack();
    IIC_Stop();
    delay_us(100);
    IIC_Start();
    IIC_Send_Byte(daddr<<1|1);
    IIC_Wait_Ack();
    for(int i=0;i<len;i++)
    {
        if(i != (len-1))
        data[i] = IIC_Read_Byte(1);
        else
        data[i] = IIC_Read_Byte(0);
    }
    IIC_Stop();
    return 0;
}


